#ifndef _OI_LT360X_CAMERADRIVER_HPP_
#define _OI_LT360X_CAMERADRIVER_HPP_

namespace Oi
{
    namespace PLScannerCore
    {
        typedef  QMap<QString, Core::RangeMapPtr> LTCameraFrame;
        typedef void (*LTCameraCallback)(const LTCameraFrame&, const QDateTime&, void*);

        class LTCameraDriver : public QObject
        {
            Q_OBJECT
         public:
             static LTCameraDriver* instance();

        public:
            LTCameraDriver() {}

        public slots:
            virtual void startCameraTimer() = 0;
            virtual void finishCameraTimer() = 0;
            virtual void cameraTimeout() = 0;

        public:
            virtual void setCallback(LTCameraCallback callback, void* data) = 0;
            virtual void start() = 0;
            virtual void close() = 0;
            virtual void stop() = 0;
            virtual void snap() = 0;
            virtual void setMaxROI() = 0;
            virtual void setOffsetX(QString, int) = 0;
            virtual void setOffsetY(QString, int) = 0;
            virtual void setWidth(QString, int) = 0;
            virtual void setHeight(QString, int) = 0;
            virtual int offsetX(QString) = 0;
            virtual int offsetY(QString) = 0;
            virtual void restartCamera() = 0;
            virtual void setExposure(int) = 0;
            virtual void setGain(double) = 0;
            virtual Math::Point2d calibrationTransformSection(const QString& camName, const Math::Point2d& source) = 0;

        public:
            virtual void flushFormula() = 0;
        };

        class LTFakeCameraDriver : public LTCameraDriver
        {
            Q_OBJECT

        public:
            LTFakeCameraDriver();
            ~LTFakeCameraDriver();

        public slots:
            void startCameraTimer();
            void finishCameraTimer();
            void cameraTimeout();

        public:
            void setCallback(LTCameraCallback callback, void* data);
            void start();
            void close();
            void stop();
            void snap();
            void setMaxROI();
            void setOffsetX(QString, int);
            void setOffsetY(QString, int);
            void setWidth(QString, int);
            void setHeight(QString, int);
            int offsetX(QString);
            int offsetY(QString);
            void restartCamera();
            void setExposure(int);
            void setGain(double);
            Math::Point2d calibrationTransformSection(const QString& camName, const Math::Point2d&);

        public:
            void flushFormula();

        private:
            OI_DISABLE_COPY(LTFakeCameraDriver);
            OI_DECLARE_IMPL(LTFakeCameraDriver);
        };

        class LTDHCameraDriver : public LTCameraDriver
        {
            Q_OBJECT

        public:
            LTDHCameraDriver();
            ~LTDHCameraDriver();

        public slots:
            void startCameraTimer();
            void finishCameraTimer();
            void cameraTimeout();

        public:
            void setCallback(LTCameraCallback callback, void* data);
            void start();
            void close();
            void stop();
            void snap();
            void setMaxROI();
            void setOffsetX(QString, int);
            void setOffsetY(QString, int);
            void setWidth(QString, int);
            void setHeight(QString, int);
            int offsetX(QString);
            int offsetY(QString);
            void restartCamera();
            void setExposure(int);
            void setGain(double);
            Math::Point2d calibrationTransformSection(const QString& camName, const Math::Point2d& source);

        public:
            void flushFormula();

        private:
            OI_DISABLE_COPY(LTDHCameraDriver);
            OI_DECLARE_IMPL(LTDHCameraDriver);
        };
    
    }
}

#endif
